/*
 * @Author: Wangjun
 * @Date: 2023-09-21 19:07:36
 * @LastEditTime: 2023-09-23 19:09:10
 * @LastEditors: Wangjun
 * @Description:
 * @FilePath: \libs\ds\table.go
 * hnxr
 */
package ds

type Table[N number] struct {
	Begin    int64 //起始位置
	Step     int64 //步长
	titles   []string
	alias    []string
	rows     []Row[N]
	mapTitle map[string]int
	mapAlias map[string]int
}

func NewTable[N number](titles []string) *Table[N] {
	t := new(Table[N])
	t.Setup(titles)
	return t
}

func (m *Table[N]) GetColumnIndex(name string) int {
	i, ok := m.mapTitle[name]
	if ok {
		return i
	}
	return -1
}

/**
 * @description: 时间转为下标
 * @param {int64} pos
 * @return {*}
 */
func (m *Table[N]) GetIndex(t int64) int {
	t = (t - m.Begin) / m.Step
	return int(t)
}

/**
 * @description: 获取原始时间
 * @param {int} idx
 * @return {*}
 */
func (m *Table[N]) GetTime(idx int) int64 {
	return (int64(idx) * m.Step) + m.Begin
}

func (m *Table[N]) Setup(titles []string) {
	m.mapTitle = make(map[string]int)
	m.mapAlias = make(map[string]int)
	m.titles = titles
	m.alias = m.titles
	for i, title := range titles {
		m.mapTitle[title] = i
		m.mapAlias[title] = i
	}
}

func (m *Table[N]) Reset() {
	for i := range m.rows {
		m.rows[i].Reset()
	}
}

func (m *Table[N]) SetRowCount(nRow int) {
	nColumn := len(m.titles)
	m.rows = make([]Row[N], nRow)
	for i := 0; i < nRow; i++ {
		m.rows[i].Setup(0, nColumn)
	}
}

func (m *Table[N]) GetRowCount() int {
	return len(m.rows)
}

func (m *Table[N]) GetColumnCount() int {
	return len(m.titles)
}

func (m *Table[N]) GetRowByTime(t int64) *Row[N] {
	return m.GetRow(m.GetIndex(t))
}

/**
 * @description: 获取一行
 * @param {int} nRow
 * @return {*}
 */
func (m *Table[N]) GetRow(nRow int) *Row[N] {
	if nRow >= len(m.rows) || nRow < 0 {
		return nil
	}
	return &m.rows[nRow]
}

func (m *Table[N]) Value(nRow, nColumn int) *N {
	row := m.GetRow(nRow)
	if row == nil {
		return nil
	}
	return row.Value(nColumn)
}

func (m *Table[N]) SetValue(nRow, nColumn int, v *N) {
	row := m.GetRow(nRow)
	if row == nil {
		return
	}
	row.SetValue(nColumn, v)
}

/**
 * @description: 设置列的别名
 * @param {int} idx
 * @param {string} alias
 * @return {*}
 */
func (m *Table[N]) SetAlias(idx int, alias string) {
	if idx >= len(m.titles) || idx < 0 {
		return
	}
	m.alias[idx] = alias

	for _, v := range m.mapAlias {
		if v == idx {
			m.mapAlias[alias] = idx
		}
	}
}

/**
 * @description: 设置全部的别名
 * @param {[]string} aliases
 * @return {*}
 */
func (m *Table[N]) SetAllAlias(aliases []string) {
	copy(m.alias, aliases)
	m.mapAlias = make(map[string]int)
	for i, alias := range m.alias {
		m.mapAlias[alias] = i
	}
}

/**
 * @description: 求和
 * @param {int} idx
 * @return {*}
 */
func (m *Table[N]) Sum(nColumn int) (fval float64, num int) {
	return
}

/**
 * @description: 求平均值
 * @param {int} idx
 * @return {*}
 */
func (m *Table[N]) Avg(nColumn int) (fval float64) {
	return
}
